﻿//XmlStrategyReport.cs
//Copyright (c) 2013 StockSharp LLC, all rights reserved.
//This code module is part of StockSharp library.
//This code is licensed under the GNU GENERAL PUBLIC LICENSE Version 3.
//See the file License.txt for the license details.
//More info on: http://stocksharp.com

namespace StockSharp.Algo.Reporting
{
	using System;
	using System.Linq;
	using System.Xml.Linq;

	using Ecng.Collections;
	using Ecng.Common;

	using StockSharp.Algo.Strategies;

	/// <summary>
	/// Генератор отчета для стратегии в формате Xml.
	/// </summary>
	public class XmlStrategyReport : StrategyReport
	{
		/// <summary>
		/// Создать генератор Xml отчетов.
		/// </summary>
		/// <param name="strategy">Стратегия, для которой необходимо сгенерировать отчет.</param>
		/// <param name="fileName">Название файла, в котором сгенерируется отчет в формате Xml.</param>
		public XmlStrategyReport(Strategy strategy, string fileName)
			: base(strategy)
		{
			if (fileName.IsEmpty())
				throw new ArgumentNullException("fileName");

			FileName = fileName;
		}

		/// <summary>
		/// Название файла, в котором сгенерируется отчет в формате Xml.
		/// </summary>
		public string FileName { get; private set; }

		/// <summary>
		/// Сгенерировать отчет в формате Xml.
		/// </summary>
		public override void Generate()
		{
			new XElement("strategy",
				new XElement("security", Strategy.Security.Id),
				new XElement("portfolio", Strategy.Portfolio.Name),
				new XElement("parameters",
					Strategy.Parameters.SyncGet(c => c.ToArray()).Select(p =>
						new XElement("parameter",
							new XElement("name", p.Name),
							new XElement("value", p.Value is TimeSpan ? Format((TimeSpan)p.Value) : p.Value)
						))),
				new XElement("totalWorkingTime", Format(Strategy.TotalWorkingTime)),
				new XElement("commission", Strategy.Commission),
				new XElement("position", Strategy.Position),
				new XElement("PnL", Strategy.PnL),
				new XElement("slippage", Strategy.Slippage),
				new XElement("latency", Format(Strategy.Latency)),
				new XElement("statisticParameters",
					Strategy.StatisticManager.Parameters.SyncGet(c => c.ToArray()).Select(p =>
						new XElement("parameter",
							new XElement("name", p.Name),
							new XElement("value", p.Value is TimeSpan ? Format((TimeSpan)p.Value) : p.Value)
						))),
				new XElement("orders",
					Strategy.Orders.OrderBy(o => o.TransactionId).Select(o =>
						new XElement("order",
							new XElement("id", o.Id),
							new XElement("transactionId", o.TransactionId),
							new XElement("direction", o.Direction),
							new XElement("time", Format(o.Time)),
							new XElement("price", o.Price),
							new XElement("averagePrice", o.GetAveragePrice()),
							new XElement("state", o.State),
							new XElement("balance", o.Balance),
							new XElement("volume", o.Volume),
							new XElement("type", o.Type),
							new XElement("slippage", Strategy.SlippageManager.GetSlippage(o)),
							new XElement("latencyRegistration", Format(o.LatencyRegistration)),
							new XElement("latencyCancellation", Format(o.LatencyCancellation))
						))),
				new XElement("trades",
					Strategy.MyTrades.OrderBy(t => t.Order.TransactionId).Select(t =>
						new XElement("trade",
							new XElement("id", t.Trade.Id),
							new XElement("transactionId", t.Order.TransactionId),
							new XElement("time", Format(t.Trade.Time)),
							new XElement("price", t.Trade.Price),
							new XElement("volume", t.Trade.Volume),
							new XElement("order", t.Order.Id),
							new XElement("PnL", Strategy.PnLManager.ProcessMyTrade(t).PnL),
							new XElement("slippage", t.GetSlippage()),
							new XElement("slippageByReRegister", Strategy.SlippageManager.GetSlippage(t))
						))),
				new XElement("stopOrders",
					Strategy.StopOrders.OrderBy(o => o.TransactionId).Select(o =>
						new XElement("order",
							new XElement("id", o.Id),
							new XElement("transactionId", o.TransactionId),
							new XElement("direction", o.Direction),
							new XElement("time", Format(o.Time)),
							new XElement("price", o.Price),
							new XElement("state", o.State),
							new XElement("volume", o.Volume),
							new XElement("latencyRegistration", Format(o.LatencyRegistration)),
							new XElement("latencyCancellation", Format(o.LatencyCancellation)),
							new XElement("derivedOrderId", o.DerivedOrder != null ? (object)o.DerivedOrder.Id : string.Empty),
							new XElement("parameters", o.Condition.Parameters.Select(p => new XElement(p.Key, p.Value)))
						)))
			).Save(FileName);
		}
	}
}
